home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 June: ROMin Holiday / ADC Developer CD (1992-06) (''ROMin Holiday'')_iso / Developer Connection - 06-1992.iso / Developer Essentials / DTS Sample Code / System 7.0 Samples / MacShell / Print.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-04  |  8.4 KB  |  321 lines  |  [TEXT/MPS ]

  1. /*
  2. ** Apple Macintosh Developer Technical Support
  3. **
  4. ** Program:     MacShell
  5. ** File:        print.c
  6. ** Written by:  Eric Soldan
  7. ** Based on:    Code from Pete "Luke" Alexander.
  8. **
  9. ** Copyright © 1989-1991 Apple Computer, Inc.
  10. ** All rights reserved.
  11. */
  12.  
  13.  
  14.  
  15. /*****************************************************************************/
  16.  
  17.  
  18.  
  19. #include "MacShell.h"            /* Get the MacShell includes/typedefs, etc.    */
  20. #include "MacShellCommon.h"        /* Get the stuff in common with rez.        */
  21. #include "MacShell.protos"        /* Get the prototypes for MacShell.            */
  22.  
  23. #ifndef __ERRORS__
  24. #include <Errors.h>
  25. #endif
  26.  
  27. #ifndef __RESOURCES__
  28. #include <Resources.h>
  29. #endif
  30.  
  31.  
  32.  
  33. /*****************************************************************************/
  34.  
  35.  
  36.  
  37. static pascal void    PrintIdleProc(void);
  38. short                gPrintPage;
  39. static DialogPtr    PrintingStatusDialog;
  40.  
  41.  
  42.  
  43. /*****************************************************************************/
  44.  
  45.  
  46.  
  47. /* This print-loop function is designed to be called under various situations.
  48. ** The big issue that it handles is finder printing.  If multiple documents
  49. ** are to be printed from the finder, the user should only see one job dialog
  50. ** for all the files.  (If a job dialog is shown for each file, how does the
  51. ** user know for which file the dialog is for?)  So, for situations where
  52. ** there is more than one file to be printed, call this code the first time
  53. ** with the firstJob boolean true.  Normally, the jobDlg boolean will also
  54. ** be true, except that under 7.0, you may be printing in the background.
  55. ** If this is the case, you don't want a job dialog for even the first file,
  56. ** and you should pass in false for the jobDlg boolean in this case.  For
  57. ** files 2-N, you should pass false for both booleans.  For regular application
  58. ** printing, you should pass true for both booleans, since the file is the
  59. ** first (only) file, and you are not in the background.
  60. **
  61. ** After calling this function to print a document, you need to call it
  62. ** again with a nil document handle.  The print record for the first (or only)
  63. ** document printed is preserved in a static variable.  This is so that the
  64. ** job dialog information can be passed on to documents 2-N in the print job.
  65. ** Calling this function with the document handle nil tells this function
  66. ** that you are done printing documents, and that the print record for the
  67. ** first job can be disposed of.
  68. */
  69.  
  70. #pragma segment Print
  71. OSErr    AppPrintDocument(FileRecHndl frHndl, Boolean jobDlg, Boolean firstJob)
  72. {
  73.     OSErr            err;
  74.     THPrint            prRecHndl;
  75.     TPPrPort        printPort;
  76.     GrafPtr            oldPort;
  77.     short            i, keepResFile, copies, fstPage, lstPage;
  78.     TPrStatus        status;
  79.     ControlHandle    proceedButton;
  80.     Rect             rct;
  81.  
  82.     static THPrint    prMergeHndl;
  83.  
  84.     if (!frHndl) {
  85.         if (prMergeHndl) {
  86.             DisposHandle((Handle)prMergeHndl);
  87.             prMergeHndl = nil;
  88.         }
  89.         return(noErr);
  90.     }
  91.  
  92.     PrintingStatusDialog = nil;
  93.  
  94.     if (!(prRecHndl = (THPrint)NewHandle(sizeof(TPrint)))) return(memFullErr);
  95.         /* If we can't generate a print record handle, we are out of here. */
  96.  
  97.     BlockMove((Ptr)&((*frHndl)->doc.print), (Ptr)(*prRecHndl), sizeof(TPrint));
  98.         /* Get the document's print info into the print record handle. */
  99.  
  100.     GetPort(&oldPort);
  101.  
  102.     DoSetCursor(&qd.arrow);
  103.     PrOpen();
  104.     err = PrError();
  105.  
  106.     if (!err) {
  107.         keepResFile = CurResFile();
  108.  
  109.         if (!(*frHndl)->doc.printRecValid) {
  110.             PrintDefault(prRecHndl);            /* The document print record was never 
  111.             err = PrError();                    ** initialized.  Now is is. */
  112.         }            
  113.         if (!err) {
  114.             PrValidate(prRecHndl);        /* Do this just 'cause Apple says so. */
  115.             err = PrError();
  116.         }
  117.         if (!err) {
  118.             if (jobDlg) {                /* User gets to click some buttons. */
  119.                 if (!(PrJobDialog(prRecHndl))) err = userCanceledErr;
  120.                 else                           err = PrError();
  121.             }
  122.         }
  123.         if (!err) {
  124.             if (!firstJob) {
  125.                 fstPage = (*prMergeHndl)->prJob.iFstPage;
  126.                 lstPage = (*prMergeHndl)->prJob.iLstPage;
  127.                 PrJobMerge(prMergeHndl, prRecHndl);
  128.                 (*prMergeHndl)->prJob.iFstPage = (*prRecHndl)->prJob.iFstPage = fstPage;
  129.                 (*prMergeHndl)->prJob.iLstPage = (*prRecHndl)->prJob.iLstPage = lstPage;
  130.                 err = PrError();
  131.             }
  132.         }
  133.  
  134.         if (!err) {            /* Put the defaulted/validated/jobDlg'ed print record in the doc. */
  135.             fstPage = (*prRecHndl)->prJob.iFstPage;
  136.             lstPage = (*prRecHndl)->prJob.iLstPage;
  137.             copies  = (*prRecHndl)->prJob.iCopies;
  138.             BlockMove((Ptr)(*prRecHndl), (Ptr)&((*frHndl)->doc.print), sizeof(TPrint));
  139.             (*frHndl)->doc.printRecValid = true;
  140.  
  141.             ParamText((*frHndl)->fileState.fss.name, nil, nil, nil);
  142.             PrintingStatusDialog = GetNewDialog(rPrStatusDlg, nil, (WindowPtr)-1);
  143.             if (PrintingStatusDialog) {
  144. #ifndef THINK_PRE_5
  145.                 GetDItem(PrintingStatusDialog, 1, &i, (Handle *)&proceedButton, &rct);
  146. #else
  147.                 GetDItem(PrintingStatusDialog, 1, &i, &proceedButton, &rct);
  148. #endif
  149.                 HiliteControl(proceedButton, 255);
  150.                     /* Setup the proceed/pause/cancel dialog with the document name. */
  151.                 (*prRecHndl)->prJob.pIdleProc = PrintIdleProc;
  152.                 UseResFile(keepResFile);
  153.                     /* Hook in the proceed/pause/cancel dialog. */
  154.             }
  155.  
  156.             for (i = 1; (i <= copies) && (!err); ++i) {
  157.  
  158.                 printPort = PrOpenDoc(prRecHndl, nil, nil);
  159.                 if (!(err = PrError())) {
  160.  
  161.                     gPrintPage = 1;
  162.                     while (gPrintPage <= lstPage) {
  163.  
  164.                         PrOpenPage(printPort, nil);
  165.  
  166.                         if (!(err = PrError()))
  167.                             DoImageDocument(frHndl);
  168.                                 /* Do the print thing here. */
  169.  
  170.                         PrClosePage(printPort);
  171.  
  172.                         if (!gPrintPage) break;
  173.                         ++gPrintPage;
  174.                     }
  175.                     gPrintPage = 0;
  176.                     PrCloseDoc(printPort);
  177.                 }
  178.             }
  179.         }
  180.  
  181.         if (
  182.             (!err) &&
  183.             ((*prRecHndl)->prJob.bJDocLoop == bSpoolLoop) &&
  184.             (!(err = PrError()))
  185.         ) {
  186.             PrPicFile(prRecHndl, nil, nil, nil, &status);
  187.             err = PrError();
  188.         }
  189.     }
  190.  
  191.     if (firstJob) prMergeHndl = prRecHndl;
  192.     else          DisposHandle((Handle)prRecHndl);
  193.  
  194.     if (PrintingStatusDialog) DisposDialog(PrintingStatusDialog);
  195.  
  196.     PrClose();
  197.     SetPort(oldPort);
  198.  
  199.     return(err);
  200. }
  201.  
  202.  
  203.  
  204. /*****************************************************************************/
  205.  
  206.  
  207.  
  208. /* PrintIdleProc will handle events in the 'Printing Status Dialog' which
  209. ** gives the user the option to 'Proceed', 'Pause', or 'Cancel' the current
  210. ** printing job during print time.
  211. **
  212. ** The buttons:
  213. **        1: Proceed
  214. **        2: Pause
  215. **        3: Cancel 
  216. */
  217.  
  218. #pragma segment Print
  219. pascal void        PrintIdleProc(void)
  220. {
  221.     Boolean                button, paused;
  222.     ControlHandle        pauseButton, proceedButton;
  223.     DialogPtr            aDialog;
  224.     EventRecord            anEvent;
  225.     GrafPtr                oldPort;
  226.     Rect                 rct;
  227.     short                item, itemType, keepResFile;
  228.  
  229.     GetPort(&oldPort);
  230.  
  231.     UseResFile(keepResFile = CurResFile());
  232.  
  233. #ifndef THINK_PRE_5
  234.     GetDItem(PrintingStatusDialog, 1, &itemType, (Handle *)&proceedButton, &rct);
  235. #else
  236.     GetDItem(PrintingStatusDialog, 1, &itemType, &proceedButton, &rct);
  237. #endif
  238.     HiliteControl(proceedButton, 255);
  239. #ifndef THINK_PRE_5
  240.     GetDItem(PrintingStatusDialog, 2, &itemType, (Handle *)&pauseButton, &rct);
  241. #else
  242.     GetDItem(PrintingStatusDialog, 2, &itemType, &pauseButton, &rct);
  243. #endif
  244.  
  245.     paused = false;
  246.     do {
  247.         if (GetNextEvent((mDownMask + mUpMask + updateMask), &anEvent)) {
  248.             if (PrintingStatusDialog != FrontWindow ())
  249.             SelectWindow(PrintingStatusDialog);
  250.  
  251.             if (IsDialogEvent(&anEvent)) {
  252.                 button = DialogSelect(&anEvent, &aDialog, &item);
  253.  
  254.                 if ((button) && (aDialog == PrintingStatusDialog)) {
  255.                     switch (item) {
  256.                         case 1:
  257.                             HiliteControl(pauseButton, 0);        /* Enable PAUSE    */
  258.                             HiliteControl(proceedButton, 255);    /* Disable PROCEED */
  259.                             paused = false;
  260.                             break;
  261.                         case 2:
  262.                             HiliteControl(pauseButton, 255);    /* Disable PAUSE  */
  263.                             HiliteControl(proceedButton, 0);    /* Enable PROCEED */
  264.                             paused = true;
  265.                             break;
  266.                         case 3:
  267.                             PrSetError(iPrAbort);               /* CANCEL printing */
  268.                             paused = false;
  269.                             break;
  270.                     }
  271.                 }
  272.             }
  273.         }
  274.     } while (paused != false); 
  275.  
  276.     SetPort(oldPort);
  277. }
  278.  
  279.  
  280.  
  281. /*****************************************************************************/
  282.  
  283.  
  284.  
  285. #pragma segment Print
  286. OSErr    PresentStyleDialog(FileRecHndl frHndl)
  287. {
  288.     OSErr        err;
  289.     THPrint        prRecHndl;
  290.  
  291.     if (!(prRecHndl = (THPrint)NewHandle(sizeof(TPrint))))
  292.         return(memFullErr);
  293.  
  294.     PrOpen();
  295.  
  296.     if (!(err = PrError())) {
  297.  
  298.         BlockMove((Ptr)&(*frHndl)->doc.print, (Ptr)*prRecHndl, sizeof(TPrint));
  299.             /* Get data, valid or not. */
  300.  
  301.         if (!(*frHndl)->doc.printRecValid) PrintDefault(prRecHndl);
  302.         else                                PrValidate(prRecHndl);
  303.         if (!(err = PrError())) {
  304.             if (PrStlDialog(prRecHndl)) {
  305.                 BlockMove((Ptr)*prRecHndl, (Ptr)&(*frHndl)->doc.print, sizeof(TPrint));
  306.                 (*frHndl)->doc.printRecValid  = true;
  307.                 (*frHndl)->fileState.docDirty = true;
  308.             }
  309.             else err = userCanceledErr;
  310.         }
  311.     }
  312.  
  313.     DisposHandle((Handle)prRecHndl);
  314.     PrClose();
  315.  
  316.     return(err);
  317. }
  318.  
  319.  
  320.  
  321.